<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{{.title}} - PodGrab</title>
    {{template "commoncss" .}}
    <link rel="stylesheet" href="/webassets/vue-multiselect.min.css">

    <style>
      img {
        display: none;
      }

      
      h2,
      h3,
      h4,
      h5 {
        margin-bottom: 1rem;
      }
      h4 {
        font-size: 2rem;
      }

      h5 {
        font-size: 1.5rem;
      }
      p {
        margin-bottom: 0.5rem;
      }
      hr {
        margin-top: 1rem;
        margin-bottom: 1rem;
      }

      .podcastItem .button {
        padding: 0 15px;
      }

      .IsPlayed-true {
        color: #555555;
      }

      /* Larger than tablet */
      @media (min-width: 750px) {
        img {
          display: block;
        }
      }
      .button-enqueue{
        display: none;
      }
      body.playerExists .button-enqueue{
        display: inline-block;
      
        [v-cloak] {
        display: none;
      }
}

    </style>
  </head>
  <body>
    <div class="container">
      {{template "navbar" .}}

      <br />{{$setting := .setting}} 
      
      <div id="app" v-cloak>

  <button @click="toggleFilters()" class="u-full-width">
    <span  v-show="!showFilters">Show Filters</span>
    <span  v-show="showFilters">Hide Filters</span>
  </button>
    <form @submit.prevent="submitFilters()" v-show="showFilters">
      <div class="row">
         <input class="columns five" type="search" @input="searchQueryUpated()" v-model="filter.q" placeholder="Search">
    <div class="columns three">    <vue-multiselect v-model="selectedSorting" :options="sortOptions" :searchable="false"
       :multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
       placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
      </vue-multiselect></div>
    <div class="columns one">      <vue-multiselect :show-pointer="false"  v-model="filter.count" :options="pagingOptions" :searchable="false"  :allow-empty="false" :close-on-select="true" :show-labels="false" placeholder="Pick a value"></vue-multiselect>
</div>
  
<div class="columns three">    <vue-multiselect v-model="selectedPlayedStatus" :options="playedStatusOptions" :searchable="false"
  :multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
  placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
 </vue-multiselect></div>
      
   
  </div>
    <div class="row">
      <vue-multiselect class="columns three" v-model="selectedPodcasts" :options="podcasts"  :show-labels="false"
      :multiple="true" :close-on-select="false" :clear-on-select="false" 
      :preserve-search="true" placeholder="Podcasts" label="Title" track-by="ID" :preselect-first="false">
        <template slot="selection" slot-scope="{ values, search, isOpen }">
          <span class="multiselect__single" v-if="values.length && !isOpen">${ values.length } options selected</span>
        </template>
      </vue-multiselect>
      <vue-multiselect class="columns three" v-model="selectedTags"  :show-labels="false" :options="tags" :multiple="true" :close-on-select="false" :clear-on-select="false" :preserve-search="true" placeholder="Tags" label="Label" track-by="ID" :preselect-first="false">
        <template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">${ values.length } options selected</span></template>
      </vue-multiselect>
      <div class="columns three">    <vue-multiselect v-model="selectedDownloadStatus" :options="downloadStatusOptions" :searchable="false"
        :multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
        placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
       </vue-multiselect></div>
       <div class="columns three">
        <a title="Play items in this page" v-if="podcastItems.length" class="button" @click="playPage()"><i class="fas fa-play"></i></a>
        <a title="Enqueue items in this page" v-if="podcastItems.length" class="button  button-enqueue" @click="enqueuePage()"><i class="fas fa-plus"></i></a>
        <a title="Reset Filters" class="button" @click="resetFilters()"><i class="fas fa-undo"></i></a>
       
      </div>
      
    </div>
    </form>
 <hr>


  <template v-for="item in podcastItems"  >
      <div class="podcasts row  podcastItem" >
        <div class="columns two">
          <img
            onerror="onImageError(this)"
            class="u-full-width"
            :src=" getEpisodeImage(item)"
            v-bind:alt="item.Title"
            loading="lazy"
          />
        </div>
        <div class="columns ten">
          <div class="row">
            <div class="columns eight">
              <h4>
                <i
                   v-if="item.IsPlayed"
                   title="Played"
                   style="color: green"
                   class="fas fa-check-circle"
                 ></i>
                 ${item.Title} <template v-if="item.Podcast && item.Podcast.Title"> // ${item.Podcast.Title}</template>
               </h4>
            </div>
            <div class="columns three">
              <small :title="item.PubDate">${getRelativeDate(item.PubDate)}</small
              >
            </div>
            <div class="columns one">
              <small> ${getFormattedDuration(item.Duration)}</small>
            </div>
          </div>
          <p class="useMore">${item.Summary }</p>

          <a
          v-if="item.IsPlayed"
          class="button button"
          title="Mark as not listened"
          @click="changePlayedStatus(item)"
          ><i class="fas fa-envelope"></i
        ></a>
       
        <a
         v-if="!item.IsPlayed"
          class="button button"
          title="Mark as listened"
          @click="changePlayedStatus(item)"
          ><i class="fas fa-envelope-open"></i
        ></a>
        <a
        v-if="!isBookmarked(item)"
          class="button button"
          title="Bookmark Episode"
          @click="changeBookmarkStatus(item)"
          ><i class="far fa-bookmark"></i
        ></a>
      
        <a
        v-if="isBookmarked(item)"
          class="button button"
          title="Remove Bookmark"
          @click="changeBookmarkStatus(item)"
          ><i class="fas fa-bookmark"></i
        ></a>

        <a
          v-if="item.DownloadPath"
          class="button"
          :href="downloadFromServer(item)"
          download
          title="Download episode file"
          ><i class="fas fa-download"></i
        ></a>
        <a
          v-if="item.DownloadPath"
          class="button button"
          @click="deleteFile(item)"
          title="Delete Podcast Episode File"
          ><i class="fas fa-trash"></i
        ></a>
        <a
        v-if="settings.AutoDownload && !item.DownloadPath"
        class="button button"
        @click="downloadToDisk(item)"
        title="Download to server"
        download
        ><i class="fas fa-cloud-download-alt"></i
      ></a>
      <a
      v-if="!settings.AutoDownload && !item.DownloadPath && item.DownloadStatus===3"
        class="button button"
        @click="downloadToDisk(item)"
        title="Download to server"
        download
        ><i class="fas fa-cloud-download-alt"></i
      ></a>
      <a
          class="button button"
          @click="openPlayer(item)"
          title="Play Episode"
          ><i class="fas fa-play"></i
        ></a>
        <a
        class="button button-enqueue"
        @click="enqueueEpisode(item)"
        title="Add Episode to existing player playlist"
        ><i class="fas fa-plus"></i
      ></a>
        </div>  <div class="columns one"></div>
      </div>
     <hr />
    </template>
    <p v-if="podcastItems.length===0">Nothing to see here! Maybe try changing the filter criteria.</p>

     
   
      <div class="row" v-if="podcastItems.length">
        <div class="columns twelve" style="text-align: center">
         
          <a v-if="filter.previousPage"
           @click=" goToPage(1)"
            class="button"
            >First</a
          >
          
          <a v-if="filter.previousPage"
           @click="goToPreviousPage()"
            class="button"
            >Previous</a 
          >
         
          
          <select name="page" id="pageDdl" v-model="filter.page" >
              <option :key="index" v-for="index in filter.totalPages" >${index}</option>
          </select>
          
          <select name="count" id="countDdl" v-model="filter.count" >
              <option :key="index" v-for="index in countOptions" >${index}</option>

        </select>
        
          <a
          v-if="filter.nextPage"
            class="button"
            @click="goToNextPage()"
            >Next</a
          >
    
        
          <a
          v-if="filter.totalPages>filter.page"
            class="button"
            @click=" goToPage(filter.totalPages)"
            >Last</a
          >
        </div>
      </div>
   
  </div>

    {{template "scripts"}}
    <script src="/webassets/luxon.min.js"></script>
    <script src="/webassets/vue-multiselect.min.js"></script>


<script>
Vue.component('vue-multiselect', window.VueMultiselect.default)

var app = new Vue({
        delimiters: ["${", "}"],
        el: "#app",
        computed:{
          page(){
            return this.filter.page;
          },
          count(){
            return this.filter.count;
          }
        },
      
        watch:{
        count(newValue,oldValue){
          if(newValue===oldValue){
            return;
          }
          this.getData();
        },
          page(newPage,oldPage){
            if(newPage==oldPage){
              return;
            }
           if(newPage==1){
             this.filter.previousPage=0;
           }else{
             this.filter.previousPage=newPage-1;
           }
           if(newPage==this.filter.totalPages){
             this.filter.nextPage=0;
           }else{
            this.filter.nextPage=newPage+1;
           }
           this.getData()
           
          },
          showFilters(current,old){
           
            if(localStorage){
              localStorage.showFilters=current
            }

          },
          
          selectedPodcasts(current,old){
            var arr=[];
            for (let index = 0; index < current.length; index++) {
              const element = current[index];
              arr.push(element.ID);
            }
            this.filter['podcastIds']=arr;
            this.submitFilters()
          },
          selectedTags(current,old){
            var arr=[];
            for (let index = 0; index < current.length; index++) {
              const element = current[index];
              arr.push(element.ID);
            }
            this.filter['tagIds']=arr;
            this.submitFilters()
          },
          selectedSorting(current,old){
            this.filter.sorting=current.Value;
            this.submitFilters()
          },
          selectedDownloadStatus(current,old){
            this.filter.isDownloaded=current.Value;
            this.submitFilters()
          },
          selectedPlayedStatus(current,old){
            this.filter.isPlayed=current.Value;
            this.submitFilters()
          },
        },
        mounted(){
          if(localStorage && localStorage.episodesFilter){
              this.filter=JSON.parse(localStorage.episodesFilter);

            }
            if(localStorage && localStorage.showFilters){
              this.showFilters=JSON.parse(localStorage.showFilters);
            }

            if(this.filter.podcastIds!=null){
              var selectedPodcasts=[];
              for(var i=0;i<this.podcasts.length;i++){
                for(var j=0;j<this.filter.podcastIds.length;j++){
                if(this.filter.podcastIds[j]===this.podcasts[i].ID){
                  selectedPodcasts.push( this.podcasts[i])
                }
              }
              }
              this.selectedPodcasts=selectedPodcasts
          }

          if(this.filter.tagIds!=null){

            var selectedTags=[];
            for(var i=0;i<this.tags.length;i++){
              for(var j=0;j<this.filter.tagIds.length;j++){
              if(this.filter.tagIds[j]===this.tags[i].ID){
                selectedTags.push( this.tags[i])
              }
            }
            }
            this.selectedTags=selectedTags
          }
            for(var i=0;i<this.sortOptions.length;i++){
              if(this.sortOptions[i].Value===this.filter.sorting){
                this.selectedSorting=this.sortOptions[i]
              }
            }

            for(var i=0;i<this.downloadStatusOptions.length;i++){
              if(this.downloadStatusOptions[i].Value===this.filter.isDownloaded.toString()){
                this.selectedDownloadStatus=this.downloadStatusOptions[i]
              }
            }

            for(var i=0;i<this.playedStatusOptions.length;i++){
              if(this.playedStatusOptions[i].Value===this.filter.isPlayed.toString()){
                this.selectedPlayedStatus=this.playedStatusOptions[i]
              }
            }
            this.filter.page=1;
          this.getData()


        },
        methods:{
          getRelativeDate(dt){
            return luxon.DateTime.fromISO(dt).toRelative()
          },
          getFormattedDuration(duration){
            var obj=luxon.Duration.fromObject({seconds:duration}).shiftTo("hours","minutes","seconds").toObject();
            str="";
            if(obj.hours>0){
                str+=obj.hours+":"
            }
            str+=obj.minutes+":"+obj.seconds;
            return str;
          },
          getEpisodeImage(item){
            return "/podcastitems/"+item.ID+"/image"
          },
          downloadFromServer(item){
            return "/podcastitems/"+item.ID+"/file"
          },
          changePlayedStatus(item){
            changePlayedStatus(item.ID,!item.IsPlayed,()=>item.IsPlayed=!item.IsPlayed)
          },
          goToPreviousPage(pageNumber){
            this.filter.page=this.filter.previousPage;
          },
          goToNextPage(pageNumber){
            this.filter.page=this.filter.nextPage;
          },
          goToPage(pageNumber){
              this.filter.page=pageNumber;
          },
          changeBookmarkStatus(item){
              isBookmarked= this.isBookmarked(item);
            
              var self=this;
              changeBookmarkStatus(item.ID,!isBookmarked,function(){
                  if(isBookmarked){
                    item.BookmarkDate=self.nildate
                  }else{
                    item.BookmarkDate="new Date().toDateString()"
                  }
              })
          },
          
          isBookmarked(item){
            return item.BookmarkDate!==this.nildate
          },
          deleteFile(item){
            deleteFile(item.ID)
          },
          downloadToDisk(item){
            downloadToDisk(item.ID)
          },
          openPlayer(item){
            openPlayer([item.ID])
          },
          enqueueEpisode(item){
            enqueueEpisode([item.ID])
          },
          searchQueryUpated(){
            var self=this;
           
            clearTimeout(this.debounce)
            this.debounce = setTimeout(() => {
              self.filter.page=1
                self.getData()
              }, 600)
          },
          saveFilter(data){
            if(localStorage){
              localStorage.episodesFilter=JSON.stringify(data);
            }
          },
          submitFilters(){
            this.filter.page=1;
            this.getData();
        
          },
          toggleFilters(){
            this.showFilters=!this.showFilters
          },
          playPage(){
            var itemIds=[];
            for(var i=0;i<this.podcastItems.length;i++){
              itemIds.push(this.podcastItems[i].ID)
            }
            openPlayer(itemIds)
          },
          enqueuePage(){
            var itemIds=[];
            for(var i=0;i<this.podcastItems.length;i++){
              itemIds.push(this.podcastItems[i].ID)
            }
            enqueueEpisode(itemIds)
          },
          updateUrl(){
            var url= new URL(window.top.location.href);
            var copy= Vue.util.extend({},this.filter);
            delete copy.totalPages
            delete copy.totalCount
            delete copy.nextPage
            delete copy.previousPage
            url.search=new URLSearchParams(copy);
            history.pushState(null,null,url.href)
          },
          resetFilters(){
            this.filter.q="";
            this.selectedPodcasts=[];
            this.selectedTags=[];
            this.selectedDownloadStatus=this.downloadStatusOptions[0];
            this.selectedPlayedStatus=this.playedStatusOptions[0];
          },
          removeStartingSlash(url){
            if(url[0]==='/'){
              return url
            }
            return "/"+url
          },
          getData(){
            var self=this;
            axios
              .get("/podcastitems",{params:this.filter})
              .then(function (response) {
                self.podcastItems= response.data.podcastItems;
                self.filter=response.data.filter;
                self.saveFilter(self.filter);
                self.updateUrl();
                setPageTitle("Episodes ("+self.filter.totalCount+")")
              })
              .catch(function (error) {
                if (error.response && error.response.data && error.response.data.message) {
                  Vue.toasted.show(error.response.data.message, {
                    theme: "bubble",
                    type: "error",
                    position: "top-right",
                    duration: 5000,
                  });
                }
              })
              .then(function () {});
              }
        },
        data: {
          socket:null,
          debouce:null,
          nildate:"0001-01-01T00:00:00Z",
          playerExists:false,
          isMobile:false,
          sortOrder:"dateAdded-asc",
          selectedSorting:"release_desc",
          selectedPodcasts:[],
          selectedTags:[],
          selectedDownloadStatus:"",
          selectedPlayedStatus:"",
          countOptions:[10,20,30,40,50,100],
          showFilters:localStorage && localStorage.showFilters && JSON.parse(localStorage.showFilters),
         
            {{ $len := len .podcastItems}}
            podcastItems: {{if gt $len 0}} {{ .podcastItems }} {{else}} [] {{end}},
            settings:{{.setting}},
            filter:{{.filter}},
            podcasts:{{.podcasts}},
            tags:{{.tags}},
            sortOptions:{{.sortOptions}},
            pagingOptions:[10,20,50,100],
            downloadStatusOptions:[{"Label":"All","Value":"nil"},{"Label":"Downloaded Only","Value":"true"},{"Label":"Not Downloaded","Value":"false"}],
            playedStatusOptions:[{"Label":"All","Value":"nil"},{"Label":"Played Only","Value":"true"},{"Label":"Unplayed only","Value":"false"}],
        }})
</script>

    <script>
      function debounce(func, wait, immediate) {
          var timeout;
          return function() {
            var context = this, args = arguments;
            var later = function() {
              timeout = null;
              if (!immediate) func.apply(context, args);
            };
            var callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
          };
        };
              function downloadToDisk(id) {
        axios
          .get("/podcastitems/" + id + "/download")
          .then(function (response) {
            Vue.toasted.show("Podcast download enqueued.", {
              theme: "bubble",
              type: "info",
              position: "top-right",
              duration: 5000,
            });
            var row = document.getElementById("podcast-" + id);
            row.remove();
          })
          .catch(function (error) {
            if (error.response && error.response.data && error.response.data.message) {
              Vue.toasted.show(error.response.data.message, {
                theme: "bubble",
                type: "error",
                position: "top-right",
                duration: 5000,
              });
            }
          })
          .then(function () {});
        return false;
      }
      function deleteFile(id) {
        axios
          .get("/podcastitems/" + id + "/delete")
          .then(function (response) {
            Vue.toasted.show("Podcast file deleted.", {
              theme: "bubble",
              type: "success",
              position: "top-right",
              duration: 5000,
            });
            var row = document.getElementById("podcast-" + id);
            row.remove();
          })
          .catch(function (error) {
            if (error.response && error.response.data && error.response.data.message) {
              Vue.toasted.show(error.response.data.message, {
                theme: "bubble",
                type: "error",
                position: "top-right",
                duration: 5000,
              });
            }
          })
          .then(function () {});
        return false;
      }
      function changePlayedStatus(id, status,success) {
        var endpoint = status ? "markPlayed" : "markUnplayed";
        axios
          .get("/podcastitems/" + id + "/" + endpoint, {
            isPlayed: status,
          })
          .then(function (response) {
            Vue.toasted.show("Podcast played status updated.", {
              theme: "bubble",
              type: "info",
              position: "top-right",
              duration: 5000,
            });
            if(success){
              success();
            }
          })
          .catch(function (error) {
            if (error.response && error.response.data && error.response.data.message) {

              Vue.toasted.show(error.response.data.message, {
                theme: "bubble",
                type: "error",
                position: "top-right",
                duration: 5000,
              });
            }
          })
          .then(function () {});
        return false;
      }
      function changeBookmarkStatus(id, status,success) {
        var endpoint = status ? "bookmark" : "unbookmark";
        axios
          .get("/podcastitems/" + id + "/" + endpoint, {
            isPlayed: status,
          })
          .then(function (response) {
            msg= status?"Bookmark Added": "Bookmark removed";
            Vue.toasted.show(msg, {
              theme: "bubble",
              type: "info",
              position: "top-right",
              duration: 5000,
            });
          if(success){
            success()
          }
          })
          .catch(function (error) {
            if (error.response && error.response.data && error.response.data.message) {
              Vue.toasted.show(error.response.data.message, {
                theme: "bubble",
                type: "error",
                position: "top-right",
                duration: 5000,
              });
            }
          })
          .then(function () {});
        return false;
      }
     
    </script>
    <script>

       const socket= getWebsocketConnection(function(event){
              const message= getWebsocketMessage("Register","Home")
              socket.send(message);
            },function(x){
              const msg= JSON.parse(x.data)
              if(msg.messageType=="NoPlayer"){
                document.body.classList.remove("playerExists")
              }
              if(msg.messageType=="PlayerExists"){
                document.body.classList.add("playerExists")
              }
            });
            function enqueueEpisode(ids){
            if(!socket){
              return
            }
           socket.send(getWebsocketMessage("Enqueue",`{"itemIds":${JSON.stringify(ids)}}`))
          }
          function enquePodcast(id){
            if(!socket){
              return
            }
            socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
          }
          function playPodcast(id){
            openPlayer("",id)
          }
    </script>
  </body>
</html>
